package com.sf.osms.dep.processor.parser;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import com.sf.osms.dep.domain.Agent;
import com.sf.osms.dep.domain.AgentFileMap;
import com.sf.osms.dep.domain.Handover;
import com.sf.osms.dep.domain.Router;
import com.sf.osms.dep.processor.exception.RouterException;
import com.sf.osms.dep.processor.model.EventModel;
import com.sf.osms.dep.processor.util.ExceptionUtils;
import com.sf.osms.dep.processor.util.HandoverLine;
import com.sf.osms.dep.processor.util.LineSplitBufferedReader;
import com.sf.osms.dep.processor.util.RouterConstants;
import com.sf.osms.dep.processor.util.StringUtil;

public class CSVEventParser implements EventParser<String[],Router>{
	
	private static Logger logger = Logger.getLogger(CSVEventParser.class);
	private static String assistDelimiter = "%";
	
	@Override
	public EventModel<String[],Router> parse(File file, Agent agentInfo) throws RouterException{
		
		EventModel<String[],Router> eventModel = new EventModel<String[],Router>();
		eventModel.setRecordList(new ArrayList<String[]>());
		
		//得到字段映射规则
		AgentFileMap parseRules = agentInfo.getAgentFileMap();
		
		//得到行分隔符
		String lineSepartor = parseRules.getLineSep();
		if(StringUtils.isEmpty(lineSepartor)){
			lineSepartor = ""; //回车键
		}
		
		//得到列分隔符
		String columnSepartor = parseRules.getColumnSep();
		if(StringUtils.isEmpty(columnSepartor)){
			//无列分隔符
			columnSepartor = RouterConstants.AGENT_FILE_COLUMN_SEPARTOR;
		}
		
		//得到文件的编码
		String encoding = parseRules.getEncoding();
		if(StringUtils.isEmpty(encoding)) {
			try {
				encoding = codeString(file);
			} catch (Exception e) {
				logger.info("***** 代理： " + agentInfo.getName() + "文件编码为空，获取文件编码失败*********",e);
			}
		}
		
		//得到文件数据的启始行
		Integer dataLine = parseRules.getDataLine() == null ? RouterConstants.AGENT_FILE_DATA_LINE_NUM :parseRules.getDataLine(); //默认为第二行为数据启始行
		//若行分隔符不是回车
		if(!"".equalsIgnoreCase(lineSepartor)){
			//lineSepartor = StringUtil.escapeRegexSpecialWord(lineSepartor);
			LineSplitBufferedReader br = null;
			try {
				br = new LineSplitBufferedReader(new InputStreamReader(new FileInputStream(file),encoding));
				br.setLineSplit(lineSepartor);
				int lineNum = 1;
				String lineStr = null;
				while((lineStr = br.readLine()) != null){
					
					if(lineNum >= dataLine){
						if(!StringUtils.isBlank(lineStr)){
							String[] columns = StringUtil.splitCSV(lineStr, columnSepartor);
							StringBuilder sb = new StringBuilder();
							for (String column : columns) {
								sb.append(""+column);
							}
							
							eventModel.getRecordList().add(removeDoubleQuotes(columns));
						}
						eventModel.setParsingLineNum(eventModel.getLineNum()+1);
						
					}
					lineNum++;
				}
			} catch (Exception e) {
				logger.error("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"出现异常");
				logger.error(ExceptionUtils.getExceptionStackString(e));
				throw new RouterException("IO exception!");
			}finally{
				if(br != null){
					try {
						br.close();
					} catch (IOException e) {
						throw new RouterException("IO exception!");
					}
				}
			}
		}else{
			logger.info("*******代理：" + agentInfo.getName() +"开始解析"+file.getAbsolutePath()+"******");
			BufferedReader br = null;
			InputStream in = null;
			try {
				in = new FileInputStream(file);
				br = new BufferedReader(new InputStreamReader(in,encoding));
				int lineNum = 1;
				String lineStr = null;
				while((lineStr = br.readLine()) != null){
					
					if(lineNum >= dataLine){
						if(!StringUtils.isBlank(lineStr)){
							//String[] columns = getStringValues(lineStr, columnSepartor);
							String[] columns = StringUtil.splitCSV(lineStr, columnSepartor);
							StringBuilder sb = new StringBuilder();
							for (String column : columns) {
								sb.append(""+column);
							}
							
							eventModel.getRecordList().add(removeDoubleQuotes(columns));
						}
						eventModel.setParsingLineNum(eventModel.getParsingLineNum()+1);
						
					}
					lineNum++;
				}
			
			} catch (Exception e) {
				logger.error("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"出现异常");
				logger.error(ExceptionUtils.getExceptionStackString(e));
				throw new RouterException("IO exception!");
			}finally{
				if(br != null){
					try {
						br.close();
					} catch (IOException e) {
						throw new RouterException("IO exception!");
					}
				}
			}
			
		}
		eventModel.setFile(file);
		logger.info("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"结束");
		return eventModel;
	}
	
	public static String[] getStringValues(String lineStr, String separator){
		separator = StringUtil.escapeRegexSpecialWord(separator);
		//"assistDelimiter" 用来辅助解析多个分隔符连续的情况，例如：“Datum vanaf:  11-01-2015;;;;;”
		//如果不使用"assistDelimiter" ，连续的多个分隔符得不到正确的解析
		if(RouterConstants.AGENT_FILE_SPLIT_NUM.equals(separator)){
			return new String[]{lineStr};
		}
		String[] values =  lineStr.replaceAll(separator, assistDelimiter+separator+assistDelimiter).split(separator);
		String[] results = new String[values.length];
		if(values != null){
			for(int i=0;i<values.length;i++){
				String str = values[i].replaceAll(assistDelimiter, "");
				results[i] = str;
			}
		}
		return results;
	}
	
	
	 /**
	  * 解析数据中的双引号
	 */
	private String[] removeDoubleQuotes(String[] values){
		if(values == null || values.length == 0){
			return values;
		}
		String[] newValues = new String[values.length];
		for(int i=0;i<values.length;i++){
			if(StringUtils.isNotEmpty(values[i])){
				newValues[i] = values[i].replaceAll("\"", " ").trim();
			}else{
				newValues[i] = values[i];
			}
			
		}
		return newValues;
	}
	
	/**
	 * 解析数据中的双引号
	 */
	private HandoverLine removeDoubleQuotes(String[] values,Integer rowNum){
		if(values == null || values.length == 0){
			return new HandoverLine(rowNum,new String[]{});
		}
		String[] newValues = new String[values.length];
		for(int i=0;i<values.length;i++){
			newValues[i] = values[i]==null?null:values[i].replaceAll("\"", " ").trim();
		}
		return  new HandoverLine(rowNum,newValues);
	}
	
	
	
	
	
	
	private String codeString(File file)
			throws Exception {

		BufferedInputStream bin = new BufferedInputStream(new FileInputStream(
				file));
		int p = (bin.read() << 8) + bin.read();
		String code = "UTF-8";

		switch (p) {
		case 29537:
		case 0xefbb:
			code = "UTF-8";
			break;
		case 0xfffe:
			code = "Unicode";
			break;
		case 0xfeff:
			code = "UTF-16BE";
			break;
		case 20338:
		case 8846:
			code = "Shift-JIS";
			break;
		default:
			code = "GBK";
		}
		if (bin != null) {
			bin.close();
		}
		return code;

	}
	
	public static void main(String[] args) throws Exception{
		/*Reader in = new FileReader("d:/user/sfhq1405/桌面/dep测试/2.txt");
		LineSplitBufferedReader br = new LineSplitBufferedReader(in);
		br.setLineSplit("5");
		String readLine = null;
		while((readLine = br.readLine()) != null){
			if(StringUtils.isBlank(readLine)){
				System.out.println("ll");
			}else{
				System.out.println(readLine);
			}
			
		}
		
		System.out.println("|2323".charAt(0));*/
		
		String[] stringValues = getStringValues("1≌2≌3≌4","≌");
		for (String string : stringValues) {
			System.out.println(string);
		}
		
	}

	@Override
	public EventModel<HandoverLine, Handover> parseHandovers(File file,
			Agent agentInfo) throws RouterException {
		EventModel<HandoverLine,Handover> eventModel = new EventModel<HandoverLine,Handover>();
		eventModel.setRecordList(new ArrayList<HandoverLine>());
		
		//得到字段映射规则
		AgentFileMap parseRules = agentInfo.getAgentFileMap();
		
		//得到行分隔符
		String lineSepartor = parseRules.getLineSep();
		if(StringUtils.isEmpty(lineSepartor)){
			lineSepartor = ""; //回车键
		}
		
		//得到列分隔符
		String columnSepartor = parseRules.getColumnSep();
		if(StringUtils.isEmpty(columnSepartor)){
			//无列分隔符
			columnSepartor = RouterConstants.AGENT_FILE_COLUMN_SEPARTOR;
		}
		
		//得到文件的编码
		String encoding = parseRules.getEncoding();
		if(StringUtils.isEmpty(encoding)) {
			try {
				encoding = codeString(file);
			} catch (Exception e) {
				logger.info("***** 代理： " + agentInfo.getName() + "文件编码为空，获取文件编码失败*********",e);
			}
		}
		
		//得到文件数据的启始行
		Integer dataLine = parseRules.getDataLine() == null ? RouterConstants.AGENT_FILE_DATA_LINE_NUM :parseRules.getDataLine(); //默认为第二行为数据启始行
		//若行分隔符不是回车
		if(!"".equalsIgnoreCase(lineSepartor)){
			//lineSepartor = StringUtil.escapeRegexSpecialWord(lineSepartor);
			LineSplitBufferedReader br = null;
			try {
				br = new LineSplitBufferedReader(new FileReader(file));
				br.setLineSplit(lineSepartor);
				int lineNum = 1;
				String lineStr = null;
				while((lineStr = br.readLine()) != null){
					
					if(lineNum >= dataLine){
						if(!StringUtils.isBlank(lineStr)){
							String[] columns = StringUtil.splitCSV(lineStr, columnSepartor);
							StringBuilder sb = new StringBuilder();
							for (String column : columns) {
								sb.append(""+column);
							}
							
							eventModel.getRecordList().add(removeDoubleQuotes(columns,lineNum));
						}else{
							eventModel.getRecordList().add(new HandoverLine(lineNum,new String[]{}));
						}
						
					}
					lineNum++;
				}
			} catch (Exception e) {
				logger.error("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"出现异常");
				logger.error(ExceptionUtils.getExceptionStackString(e));
				throw new RouterException("IO exception!");
			}finally{
				if(br != null){
					try {
						br.close();
					} catch (IOException e) {
						throw new RouterException("IO exception!");
					}
				}
			}
		}else{
			logger.info("*******代理：" + agentInfo.getName() +"开始解析"+file.getAbsolutePath()+"******");
			BufferedReader br = null;
			InputStream in = null;
			try {
				in = new FileInputStream(file);
				br = new BufferedReader(new InputStreamReader(in,encoding));
				int lineNum = 1;
				String lineStr = null;
				while((lineStr = br.readLine()) != null){
					
					if(lineNum >= dataLine){
						if(!StringUtils.isBlank(lineStr)){
							//String[] columns = getStringValues(lineStr, columnSepartor);
							String[] columns = StringUtil.splitCSV(lineStr, columnSepartor);
							StringBuilder sb = new StringBuilder();
							for (String column : columns) {
								sb.append(""+column);
							}
							
							eventModel.getRecordList().add(removeDoubleQuotes(columns,lineNum));
						}else{
							eventModel.getRecordList().add(new HandoverLine(lineNum,new String[]{}));
						}
						
					}
					lineNum++;
				}
			
			} catch (Exception e) {
				logger.error("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"出现异常");
				logger.error(ExceptionUtils.getExceptionStackString(e));
				throw new RouterException("IO exception!");
			}finally{
				if(br != null){
					try {
						br.close();
					} catch (IOException e) {
						throw new RouterException("IO exception!");
					}
				}
			}
			
		}
		eventModel.setFile(file);
		logger.info("*******代理：" + agentInfo.getName() + "解析"+file.getAbsolutePath()+"结束");
		return eventModel;
	}
	
}
